#include "at_module.h"
#include "at_parser.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define     MAX_PACKET_SIZE     1460

//结构体初始化
void module_init(ATModuleConfig* cfg)
{
    memset(cfg,0,sizeof(ATModuleConfig));
}

//模块上电
void module_poweron(ATModuleConfig* cfg)
{
    if(cfg && cfg->fpPowerOn)
    {
        cfg->fpPowerOn(1);
        cfg->eModuleStatus = AT_MODULE_IDLE;
    }
}

//TCP接收回调
void module_tcp_receive_urc(void* arg,const char* pkt,int len)
{
    ATModuleConfig* cfg = (ATModuleConfig*)arg;
    uint8_t* packet = (uint8_t*)malloc(len);
    int pktLen;
    int id;
    if(packet == NULL)
        return;
    if(cfg->atTcpCfg->fpParserTcpReceive)
    {
        cfg->atTcpCfg->fpParserTcpReceive(&id,pkt,len,packet,&pktLen);
        if(cfg->fpTcpReceiveCallback)
            cfg->fpTcpReceiveCallback(id,packet,pktLen);
    }
    free(packet);
}

//MQTT PUB回调
void module_mqtt_pub_urc(void* arg,const char* cmd,int len)
{
    ATModuleConfig* cfg = (ATModuleConfig*)arg;
    int  payloadLen = 0;
    int qos = 0;
    char* topic = (char*)malloc(256);
    if(topic == NULL)
        return;
    char* payload = (char*)malloc(len);
    if(payload == NULL)
    {
        free(topic);
        return;
    }
    
    if(cfg->atMqttCfg->fpParserMqttPub)
    {
        cfg->atMqttCfg->fpParserMqttPub(cmd,len,topic,payload,&payloadLen,&qos);
        if(cfg->fpMqttPubCallback)
            cfg->fpMqttPubCallback(topic,payload,payloadLen,qos);
    }
    free(topic);
    free(payload);
}

void module_tcp_disconnect_urc(void* arg,const char* cmd,int len)
{
    ATModuleConfig* cfg = (ATModuleConfig*)arg;
    cfg->iTcpConnectFlag = 0;
	if(cfg->fpTcpDisconnectCallback)
		cfg->fpTcpDisconnectCallback(0);
}

void module_mqtt_disconnect_urc(void* arg,const char* cmd,int len)
{
    ATModuleConfig* cfg = (ATModuleConfig*)arg;
    cfg->iMqttConnectFlag = 0;
}

//模块开始运行初始化指令
MODULE_ERRPO module_start(ATModuleConfig* cfg)
{
    if(cfg)
    {
        int i = 0;
        if(cfg->eModuleStatus == AT_MODULE_POWER_DOWN)
            return MODULE_ERR_PWD;
        if(cfg->eModuleStatus == AT_MODULE_SLEEP)
            return MODULE_ERR_SLEEP;
        at_parser_init(&cfg->atConfig);
        for(i = 0;i < cfg->iInitCmdNum;i++)
        {
            AT_ERROR err = at_parser_send_wait(&cfg->atConfig,
                                    cfg->pInitCmd[i].at_cmd,
                                    cfg->pInitCmd[i].at_len,
                                    cfg->pInitCmd[i].at_will,
                                    0,
                                    cfg->pInitCmd[i].timeout,
                                    cfg->pInitCmd[i].resendCnt
                                    );
            if(err != AT_ERR_NONE)
                return MODLUE_ERR_INIT;
        }
        
        at_parser_register_urc(&cfg->atConfig,cfg->atTcpCfg->pcReceiveURC,module_tcp_receive_urc,cfg);
        at_parser_register_urc(&cfg->atConfig,cfg->atTcpCfg->pcDisconnectURC,module_tcp_disconnect_urc,cfg);
        at_parser_register_urc(&cfg->atConfig,cfg->atMqttCfg->pcMqttPubURC,module_mqtt_pub_urc,cfg);
        at_parser_register_urc(&cfg->atConfig,cfg->atMqttCfg->pcMqttDisconnectURC,module_mqtt_disconnect_urc,cfg);
        
        
        cfg->eModuleStatus = AT_MODULE_IDLE;
        return MODULE_ERR_NONE;
    }
    return MODULE_ERR_PARAM;
}

//模块获取IP信息
const char* module_get_ip(ATModuleConfig* cfg)
{
    if(cfg)
    {
        int ret;
        if(cfg->atIpCfg->fpMakeCheckIp)
        {
            const char *buff;
            AT_ERROR err = at_parser_send_wait(&cfg->atConfig,
                                cfg->atIpCfg->pcCheckIp,
                                strlen(cfg->atIpCfg->pcCheckIp),
                                cfg->atIpCfg->pcCheckIpSuccess,
                                &buff,
                                DEFAULT_TIMEOUT,
                                DEFAULT_RESEND_TIME
                                );
            if(err == AT_ERR_NONE)
            {
                if(cfg->atIpCfg->fpMakeCheckIp)
                {
                    ret = cfg->atIpCfg->fpMakeCheckIp(buff,strlen(buff),cfg->cIp);
                    if(ret != NULL)
                    {
                        return cfg->cIp;
                    }
                }
                err = at_parser_send_wait(&cfg->atConfig,
                                cfg->atIpCfg->pcGetIp,
                                strlen(cfg->atIpCfg->pcGetIp),
                                cfg->atIpCfg->pcGetIpSuccess,
                                &buff,
                                cfg->atIpCfg->iTimeOut,
                                DEFAULT_RESEND_TIME
                                );
                if(err == AT_ERR_NONE)
                {
                    if(cfg->atIpCfg->fpMakeGetIp)
                    {
                        ret = cfg->atIpCfg->fpMakeGetIp(buff,strlen(buff),cfg->cIp);
                        if(ret)
                        {
                            return cfg->cIp;
                        }
                    }
                }
            }
        }
    }
    cfg->iIpFlag = 0;
    return NULL;
}

//连接TCP服务器
MODULE_ERRPO module_tcp_connect(ATModuleConfig* cfg,const char* ip,uint16_t port)
{
    if(cfg)
    {
        char buff[256];
        AT_ERROR err;
        if(cfg->eModuleStatus != AT_MODULE_IDLE)
            return MODULE_ERR_NO_INIT;
        if(cfg->iTcpConnectFlag)
            return MODULE_ERR_TCP_ALREADY;
        cfg->atTcpCfg->fpMakeTcpConnect(1,ip,port,buff,256);
        err = at_parser_send_wait(&cfg->atConfig,
                                buff,
                                strlen(buff),
                                cfg->atTcpCfg->pcConnectSuccess,
                                0,
                                cfg->atTcpCfg->iTimeout,
                                0
                                );
        if(err == AT_ERR_NONE)
        {
            cfg->iTcpConnectFlag = 1;
            return MODULE_ERR_NONE;
        }
        else
        {
            return MODULE_ERR_TCP_FAIL;
        }
    }
    return MODULE_ERR_PARAM;
}

//发送数据
MODULE_ERRPO module_tcp_send(ATModuleConfig* cfg,const uint8_t* pkt,int len)
{
    if(cfg)
    {
        char *buff = 0;
        AT_ERROR err;
        if(cfg->eModuleStatus != AT_MODULE_IDLE)
            return MODULE_ERR_NO_INIT;
        if(!cfg->iTcpConnectFlag)
            return MODULE_ERR_TCP_NONE;
        
        buff = (char*)malloc(MAX_PACKET_SIZE);
        if(buff == NULL)
            return MODULE_ERR_PARAM;
        if(cfg->atTcpCfg->fpMakeTcpSendHead)
        {
            cfg->atTcpCfg->fpMakeTcpSendHead(1,pkt,len,buff,MAX_PACKET_SIZE);
            err = at_parser_send_wait(&cfg->atConfig,
                                buff,
                                strlen(buff),
                                cfg->atTcpCfg->pcSendHead,
                                0,
                                3000,
                                DEFAULT_RESEND_TIME
                                );
            if(err != AT_ERR_NONE)
            {
                if(err == AT_ERR_ERROR)
                    cfg->iTcpConnectFlag = 0;
                free(buff);
                return MODULE_ERR_TCP_FAIL;
            }
        }
        cfg->atTcpCfg->fpMakeTcpSend(1,pkt,len,buff,MAX_PACKET_SIZE);
        err = at_parser_send_wait(&cfg->atConfig,
                                buff,
                                len,
                                cfg->atTcpCfg->pcSendSuccess,
                                0,
                                cfg->atTcpCfg->iTimeout,
                                DEFAULT_RESEND_TIME
                                );
        free(buff);
        if(err == AT_ERR_NONE)
        {
            return MODULE_ERR_NONE;
        }
        else
        {
            if(err == AT_ERR_ERROR)
                cfg->iTcpConnectFlag = 0;
            return MODULE_ERR_TCP_FAIL;
        }
    }
    return MODULE_ERR_PARAM;
}

//读入数据
MODULE_ERRPO module_tcp_read(ATModuleConfig* cfg,uint8_t* buff,int *len,int maxLen,int timeout)
{
	if(cfg)
    {
        AT_ERROR err;
        if(cfg->eModuleStatus != AT_MODULE_IDLE)
            return MODULE_ERR_NO_INIT;
        if(!cfg->iTcpConnectFlag)
            return MODULE_ERR_TCP_NONE;
        err = at_parser_read(&cfg->atConfig, buff,len,maxLen,timeout);
		/*
		待完善
		if(*len)
		{
			if(strstr((const char* )buff,cfg->atTcpCfg->pcReceiveURC))
			{
				
			}
		}
		*/
        return MODULE_ERR_NONE;
    }
    return MODULE_ERR_PARAM;
}

//断开连接
MODULE_ERRPO module_tcp_disconnect(ATModuleConfig* cfg)
{
    if(cfg)
    {
        char buff[128];
        AT_ERROR err;
        if(cfg->eModuleStatus != AT_MODULE_IDLE)
            return MODULE_ERR_NO_INIT;
        //if(cfg->iTcpConnectFlag)
            //return MODULE_ERR_TCP_ALREADY;
        cfg->atTcpCfg->fpMakeTcpDisconnect(1,buff,128);
        err = at_parser_send_wait(&cfg->atConfig,
                                buff,
                                strlen(buff),
                                cfg->atTcpCfg->pcDisconnectHead,
                                0,
                                cfg->atTcpCfg->iTimeout,
                                DEFAULT_RESEND_TIME
                                );
        
        cfg->iTcpConnectFlag = 0;
        if(err != AT_ERR_TIMEOUT)
            return MODULE_ERR_NONE;
        else
            return MODULE_ERR_NO_ACK;
    }
    return MODULE_ERR_PARAM;
}

//MQTT参数配置
MODULE_ERRPO module_mqtt_config(ATModuleConfig* cfg)
{
    if(cfg)
    {
        int i = 0;
        if(cfg->eModuleStatus == AT_MODULE_POWER_DOWN)
            return MODULE_ERR_PWD;
        if(cfg->eModuleStatus == AT_MODULE_SLEEP)
            return MODULE_ERR_SLEEP;
        for(i = 0;i < cfg->atMqttCfg->iMqttCfgCmdNum;i++)
        {
            AT_ERROR err = at_parser_send_wait(&cfg->atConfig,
                                    cfg->atMqttCfg->pMqttConfig[i].at_cmd,
                                    cfg->atMqttCfg->pMqttConfig[i].at_len,
                                    cfg->atMqttCfg->pMqttConfig[i].at_will,
                                    0,
                                    cfg->atMqttCfg->pMqttConfig[i].timeout,
                                    cfg->atMqttCfg->pMqttConfig[i].resendCnt
                                    );
            if(err != AT_ERR_NONE)
                return MODULE_ERR_MQTT_FAIL;
        }
        return MODULE_ERR_NONE;
    }
    return MODULE_ERR_PARAM;
}

//连接MQTT服务器
MODULE_ERRPO module_mqtt_connect(ATModuleConfig* cfg,const char* ip,uint16_t port)
{
    if(cfg)
    {
        char buff[128];
        AT_ERROR err;
        if(cfg->eModuleStatus != AT_MODULE_IDLE)
            return MODULE_ERR_NO_INIT;
        if(cfg->iMqttConnectFlag)
            return MODULE_ERR_MQTT_ALREADY;
        cfg->atMqttCfg->fpMakeMqttTcpConnect(ip,port,buff,128);
        err = at_parser_send_wait(&cfg->atConfig,
                                buff,
                                strlen(buff),
                                cfg->atMqttCfg->pcMqttConnectSuccess,
                                0,
                                cfg->atMqttCfg->iTimeout,
                                1
                                );
        
        if(err == AT_ERR_NONE)
        {
            cfg->iMqttConnectFlag = 1;
            return MODULE_ERR_NONE;
        }
        else
        {
            return MODULE_ERR_TCP_FAIL;
        }
    }
    return MODULE_ERR_PARAM;
}

//登录MQTT服务器
MODULE_ERRPO module_mqtt_login(ATModuleConfig* cfg,const char* clientID,const char* username,const char* passwrod)
{
    if(cfg)
    {
        char *buff = 0;
        AT_ERROR err;
        if(cfg->eModuleStatus != AT_MODULE_IDLE)
            return MODULE_ERR_NO_INIT;
        if(!cfg->iMqttConnectFlag)
            return MODULE_ERR_MQTT_NONE;
        
        buff = (char*)malloc(MAX_PACKET_SIZE);
        if(buff == NULL)
            return MODULE_ERR_PARAM;
        cfg->atMqttCfg->fpMakeMqttConncet(clientID,username,passwrod,buff,MAX_PACKET_SIZE);
        err = at_parser_send_wait(&cfg->atConfig,
                                buff,
                                strlen(buff),
                                cfg->atMqttCfg->pcMqttLoginSuccess,
                                0,
                                cfg->atMqttCfg->iTimeout,
                                1
                                );
        free(buff);
        if(err == AT_ERR_NONE)
        {
            return MODULE_ERR_NONE;
        }
        else
        {
            cfg->iMqttConnectFlag = 0;
            return MODULE_ERR_MQTT_FAIL;
        }
    }
    return MODULE_ERR_PARAM;
}

//推送
MODULE_ERRPO module_mqtt_pub(ATModuleConfig* cfg,const char* topic,const char* payload,int payloadLen,int qos)
{
    if(cfg)
    {
        char *buff = 0;
        AT_ERROR err;
        if(cfg->eModuleStatus != AT_MODULE_IDLE)
            return MODULE_ERR_NO_INIT;
        if(!cfg->iMqttConnectFlag)
            return MODULE_ERR_MQTT_NONE;
        
        buff = (char*)malloc(MAX_PACKET_SIZE);
        if(buff == NULL)
            return MODULE_ERR_PARAM;
        
        if(cfg->atMqttCfg->fpMakeMqttPub)
        {
            cfg->atMqttCfg->fpMakeMqttPub(topic,payload,payloadLen,qos,buff,MAX_PACKET_SIZE);
            err = at_parser_send_wait(&cfg->atConfig,
                                buff,
                                strlen(buff),
                                cfg->atMqttCfg->pcMqttPubHead,
                                0,
                                cfg->atMqttCfg->iTimeout,
                                1
                                );
        }
        cfg->atMqttCfg->fpMakeMqttPubMessage(topic,payload,payloadLen,qos,buff,MAX_PACKET_SIZE);
        err = at_parser_send_wait(&cfg->atConfig,
                                buff,
                                strlen(buff),
                                cfg->atMqttCfg->pcMqttPubSuccess,
                                0,
                                cfg->atMqttCfg->iTimeout,
                                1
                                );
        
        free(buff);
        if(err == AT_ERR_NONE)
        {
            return MODULE_ERR_NONE;
        }
        else
        {
            if(err == AT_ERR_ERROR)
                cfg->iMqttConnectFlag = 0;
            return MODULE_ERR_MQTT_FAIL;
        }
    }
    return MODULE_ERR_PARAM;
}

//订阅
MODULE_ERRPO module_mqtt_sub(ATModuleConfig* cfg,const char* topic,int qos)
{
    if(cfg)
    {
        char buff[256];
        AT_ERROR err;
        if(cfg->eModuleStatus != AT_MODULE_IDLE)
            return MODULE_ERR_NO_INIT;
        if(!cfg->iMqttConnectFlag)
            return MODULE_ERR_MQTT_NONE;
        
        cfg->atMqttCfg->fpMakeMqttSub(topic,qos,buff,256);
        err = at_parser_send_wait(&cfg->atConfig,
                                buff,
                                strlen(buff),
                                cfg->atMqttCfg->pcMqttSubSuccess,
                                0,
                                cfg->atMqttCfg->iTimeout,
                                1
                                );
        if(err == AT_ERR_NONE)
        {
            return MODULE_ERR_NONE;
        }
        else
        {
            if(err == AT_ERR_ERROR)
                cfg->iMqttConnectFlag = 0;
            return MODULE_ERR_MQTT_FAIL;
        }
    }
    return MODULE_ERR_PARAM;
}

//取消订阅
MODULE_ERRPO module_mqtt_unsub(ATModuleConfig* cfg,const char* topic,int qos)
{
    if(cfg)
    {
        char buff[256];
        AT_ERROR err;
        if(cfg->eModuleStatus != AT_MODULE_IDLE)
            return MODULE_ERR_NO_INIT;
        if(!cfg->iMqttConnectFlag)
            return MODULE_ERR_MQTT_NONE;
        
        cfg->atMqttCfg->fpMakeMqttUnSub(topic,qos,buff,256);
        err = at_parser_send_wait(&cfg->atConfig,
                                buff,
                                strlen(buff),
                                cfg->atMqttCfg->pcMqttUnsubSuccess,
                                0,
                                cfg->atMqttCfg->iTimeout,
                                1
                                );
        if(err == AT_ERR_NONE)
        {
            return MODULE_ERR_NONE;
        }
        else
        {
            if(err == AT_ERR_ERROR)
                cfg->iMqttConnectFlag = 0;
            return MODULE_ERR_MQTT_FAIL;
        }
    }
    return MODULE_ERR_PARAM;
}

//登出
MODULE_ERRPO module_mqtt_logout(ATModuleConfig* cfg)
{
    if(cfg)
    {
        AT_ERROR err;
        char buff[128];
        if(cfg->eModuleStatus != AT_MODULE_IDLE)
            return MODULE_ERR_NO_INIT;
		/*
        if(!cfg->iMqttConnectFlag)
            return MODULE_ERR_MQTT_NONE;
        */
        cfg->atMqttCfg->fpMakeMqttLogout(buff,128);
        err = at_parser_send_wait(&cfg->atConfig,
                                buff,
                                strlen(buff),
                                cfg->atMqttCfg->pcMqttLogoutSuccess,
                                0,
                                cfg->atMqttCfg->iTimeout,
                                DEFAULT_RESEND_TIME
                                );
        if(err == AT_ERR_NONE)
        {
            cfg->iMqttConnectFlag = 0;
            return MODULE_ERR_NONE;
        }
        else
        {
            return MODULE_ERR_MQTT_FAIL;
        }
    }
    return MODULE_ERR_PARAM;
}

//主动断开连接
MODULE_ERRPO module_mqtt_disconnect(ATModuleConfig* cfg)
{
    if(cfg)
    {
        AT_ERROR err;
        char buff[128];
        if(cfg->eModuleStatus != AT_MODULE_IDLE)
            return MODULE_ERR_NO_INIT;
        /*
        if(!cfg->iMqttConnectFlag)
            return MODULE_ERR_MQTT_NONE;
        */
        cfg->atMqttCfg->fpMakeMqttDisconnect(buff,128);
        err = at_parser_send_wait(&cfg->atConfig,
                                buff,
                                strlen(buff),
                                cfg->atMqttCfg->pcMqttDisconnectSuccess,
                                0,
                                cfg->atMqttCfg->iTimeout,
                                DEFAULT_RESEND_TIME
                                );
		cfg->iMqttConnectFlag = 0;
        if(err == AT_ERR_NONE)
        {
            return MODULE_ERR_NONE;
        }
        else
        {
            return MODULE_ERR_MQTT_FAIL;
        }
    }
    return MODULE_ERR_PARAM;
}

//设置TCP接收数据回调函数
void module_set_tcp_receive_callback(ATModuleConfig* cfg,pTcpReceivePacket f)
{
    cfg->fpTcpReceiveCallback = f;
}

//设置TCP连接意外断开处理回调函数
void module_set_tcp_disconnect_callback(ATModuleConfig* cfg,pTcpDisconnectURC f)
{
	cfg->fpTcpDisconnectCallback = f;
}

//设置MQTT的Pub接收回调函数
void module_set_mqtt_pub_callback(ATModuleConfig* cfg,pMqttPubPacket f)
{
    cfg->fpMqttPubCallback = f;
}

//AT模块执行循环
void module_loop(ATModuleConfig* cfg)
{
    if(cfg)
        at_parser_loop(&cfg->atConfig);
}
